<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    

<script>
// 继承(类之间的关系)

 // 构造函数继承(对象冒充继承)
// 原理: 在子类中调用父类, 并修改父类中的this指向
function Cat(n,c){// 构造函数(父类)
    // this -> Cat的实例对象
    this.name = n;
    this.color = c;
}
Cat.prototype.skill = function (){
    console.log( '抓老鼠' )
}
// var cat1 = new Cat('小白','white');
// console.log( cat1.name );
// console.log( cat1.color );
// cat1.skill();

// 需求: Dog实例也要有name和color这些属性,也要能抓老鼠

function Dog(f,n,c){// 构造函数(子类)
    // this -> Dog的实例对象
    this.food = f;
    // Cat.bind(this,n,c)();// 构造函数继承(对象冒充继承)
    Cat.call(this,n,c);// 构造函数继承(对象冒充继承)
    // Cat.apply(this,[n,c]);// 构造函数继承(对象冒充继承)
}
var dog1 = new Dog('shi','大黄','yellow');
console.log( dog1.food );
console.log( dog1.name );
console.log( dog1.color );
dog1.skill();// 报错 dog1.skill is not a function

// dog1 => Dog.prototype => Object.prototype => null 


 // 原型继承
// 原理: 修改实例对象的原型链
function Cat(n,c){// 构造函数(父类)
    // this -> Cat的实例对象
    this.name = n;
    this.color = c;
}
Cat.prototype.skill = function (){
    console.log( '抓老鼠' )
}

function Dog(f){// 构造函数(子类)
    // this -> Dog的实例对象
    this.food = f;
}
Dog.prototype = Cat.prototype;// 原型继承
// dog1 => Dog.prototype = Cat.prototype => Object.prototype => null

// Dog.prototype = new Cat();// 原型继承
// dog1 => Dog.prototype = Cat的实例对象 => Cat的实例对象.__proto__ = Cat.prototype => Object.prototype => null

var dog1 = new Dog('骨头');
console.log( dog1 );
console.log( dog1.food );// '骨头'
console.log( dog1.name );// undefined
console.log( dog1.color );// undefined
dog1.skill();// '抓老鼠' 


// 混合继承(组合继承)
// 原理: 构造函数继承 + 原型继承
function Cat(n,c){// 构造函数(父类)
    // this -> Cat的实例对象
    this.name = n;
    this.color = c;
}
Cat.prototype.skill = function (){
    console.log( '抓老鼠' )
}

function Dog(f,n,c){// 构造函数(子类)
    // this -> Dog的实例对象
    this.food = f;
    Cat.call(this,n,c);// 构造函数继承
}
Dog.prototype = Cat.prototype;// 原型继承
var dog1 = new Dog('骨头','啊黄','yellow');
console.log( dog1.food );
console.log( dog1.name );
console.log( dog1.color );
dog1.skill();

</script>
</body>
</html>